import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import { findDOMNode } from 'react-dom';
import { DragSource, DropTarget } from 'react-dnd';

const style = {
	border: '1px dashed gray',
	padding: '0.5rem 1rem',
	marginBottom: '.5rem',
	backgroundColor: 'white',
  cursor: 'move',
}
const oneLevelSource = {
  beginDrag(props) {
    return {
			id: props.id,
			index: props.index
		}
  }
}
const oneLevelTarget = {
	hover(props, monitor, component) {
    // 拖拽元素未知的索引值
    const dragIndex = monitor.getItem().index;
    // 要放置元素位置的索引值
		const hoverIndex = props.index;
		// 移动到自己的元素上
		if (dragIndex === hoverIndex) {
			return;
    }
    // 返回元素的大小及其相对于视口的位置
    const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
    // 获取元素高度的一半
    const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
    // 
		const clientOffset = monitor.getClientOffset();
    // 拖拽移动的距离
		const hoverClientY = clientOffset.y - hoverBoundingRect.top;
    // 移动的距离不超过元素高度的一半时，都不移动
		if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
			return;
		}
		if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
			return;
    }
    props.moveAction(dragIndex, hoverIndex, 'oneLevel');
		// 变化索引值
		monitor.getItem().index = hoverIndex;
	},
}
@DragSource('oneLevel', oneLevelSource, (connect, monitor) => {
  return {
    connectDragSource: connect.dragSource(),
	  isDragging: monitor.isDragging(),
  }
})
@DropTarget('oneLevel', oneLevelTarget, (connect) => {
  return {
    connectDropTarget: connect.dropTarget(),
  }
})
export default class OneLevelItem extends Component {
  static propTypes = {
    connectDragSource: PropTypes.func.isRequired,
		connectDropTarget: PropTypes.func.isRequired,
		index: PropTypes.number.isRequired,
		isDragging: PropTypes.bool.isRequired,
		id: PropTypes.any.isRequired,
		name: PropTypes.string.isRequired,
		moveAction: PropTypes.func.isRequired,
  }
  
  clickAction = () => {
    const { id, clickAction } = this.props;
    clickAction(id);
  }
  render() {
    const { name, isDragging, connectDragSource, connectDropTarget } = this.props;
    const opacity = isDragging ? 0.5 : 1;
    return (
      connectDragSource(
        connectDropTarget(<div onClick={this.clickAction} style={{ ...style, opacity }}>{ name }</div>)
      )
    )
  }
}
